using System.Collections.Generic;
using System.Linq;
using SapaFinance.Domain.Extensions;

namespace SapaFinance.Domain.BusinessLogic
{
    public interface IValidatorComposite<T> : IValidator<T>, IValidatorResult where T : class
    {
        IValidatorComposite<T> AddRule(IValidator<T> rule);
    }

    public class ValidatorComposite<T> : IValidatorComposite<T> where T : class
    {
        private readonly ISet<string> _brokenRules;
        private readonly ICollection<IValidator<T>> _rulesToCheck;

        public ValidatorComposite()
        {
            _brokenRules = new HashSet<string>();
            _rulesToCheck = new List<IValidator<T>>();
        }

        #region IValidatorComposite<T> Members

        public IValidatorComposite<T> AddRule(IValidator<T> rule)
        {
            _rulesToCheck.Add(rule);
            return this;
        }

        public bool IsValid(T entity)
        {
            foreach (var validator in _rulesToCheck.Where(validator => !validator.IsValid(entity)))
                _brokenRules.Add(validator.GetType().GetDisplayName());
            return !_brokenRules.Any();
        }

        public void SetObjectToMatch(T entity)
        {
            foreach (var validator in _rulesToCheck)
                validator.SetObjectToMatch(entity);
        }

        public IEnumerable<string> GetBrokenRules()
        {
            return _brokenRules;
        }

        #endregion
    }
}